{
 "cells": [
  {
   "cell_type": "raw",
   "id": "2aca8168-62ec-4bba-93f0-73da08cd1920",
   "metadata": {},
   "source": [
    "---\n",
    "sidebar_position: 1\n",
    "title: Summarization\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf13f702",
   "metadata": {},
   "source": [
    "[![Open In Collab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ai-forever/gigachain/blob/master/docs/extras/use_cases/summarization.ipynb)\n",
    "\n",
    "## Варианты использования\n",
    "\n",
    "Предположим, у вас есть набор документов (PDF-файлы, страницы Notion, вопросы клиентов и т. д.), и вы хотите обобщить их содержимое.\n",
    "\n",
    "LLM являются отличным инструментом для этого, учитывая их навыки понимания и синтеза текста.\n",
    "\n",
    "В этом пошаговом руководстве мы рассмотрим, как выполнить обобщение документов с помощью LLM."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e233997",
   "metadata": {},
   "source": [
    "![Use case 1](../../static/img/summarization_use_case_1.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4715b4ff",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Обзор\n",
    "\n",
    "Основной вопрос при создании сумматора — как передать ваши документы в контекстное окно LLM. Два распространенных подхода к этому:\n",
    "\n",
    "1.  `Stuff`: просто \"сложите\" все свои документы в один промпт. Это самый простой подход, который используется для документов, которые можно поместить целиком в контекст запроса.\n",
    "\n",
    "2. `Map-reduce`: Суммаризирует каждый документ по-отдельности на шаге map, затем суммаризирует все результаты на шаге reduce для получения финального саммари.\n",
    "\n",
    "3. `Refine`: Суммаризирует часть документов, затем добавляет новые документы к полученной суммаризации и снова суммаризирует.\n",
    "\n",
    "4. `Conditional`: Суммаризует документы исходя из длины документы, либо методом Stuff, либо Map-reduce"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "08ec66bc",
   "metadata": {},
   "source": [
    "![Use case 2](../../static/img/summarization_use_case_2.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bea785ac",
   "metadata": {},
   "source": [
    "## Quickstart\n",
    "\n",
    "Для наглядности любой конвейер можно обернуть в один объект: `load_summarize_chain`.\n",
    "\n",
    "Предположим, мы хотим подвести итог записи в блоге. Мы можем создать это с помощью нескольких строк кода.\n",
    "\n",
    "Сначала установите переменные среды и установите пакеты:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "578d6a90",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install openai tiktoken chromadb gigachain\n",
    "\n",
    "# Set env var OPENAI_API_KEY or load from a .env file\n",
    "# import dotenv\n",
    "\n",
    "# dotenv.load_dotenv()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "36138740",
   "metadata": {},
   "source": [
    " При использоваии параметра `chain_type=\"stuff\"` следует выбирать LLM с большим размером контекстного окна, например:\n",
    "\n",
    "* 16k token OpenAI `gpt-3.5-turbo-16k` \n",
    "* 100k token Anthropic [Claude-2](https://www.anthropic.com/index/claude-2)\n",
    "\n",
    "Также можно использовать другие типы суммаризации `chain_type=\"map_reduce\"` или `chain_type=\"refine\"` (подробнее смомтрите раздел [Option 3. Refine](/docs/docs/use_cases/summarization.ipynb))."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "fd271681",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'В данном тексте рассматривается использование технологии машинного обучения на основе нейронных сетей для создания и управления автономными агентами. Описываются проблемы, связанные с планированием и выполнением задач на длительные периоды времени, а также с устойчивостью моделей к ошибкам. Обсуждаются преимущества использования технологии нейронных сетей для планирования и решения задач, а также ее потенциал для создания более эффективных и надежных систем искусственного интеллекта.'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain.chains.summarize import load_summarize_chain\n",
    "from langchain.chat_models.gigachat import GigaChat\n",
    "from langchain.document_loaders import WebBaseLoader\n",
    "\n",
    "loader = WebBaseLoader(\"https://lilianweng.github.io/posts/2023-06-23-agent/\")\n",
    "docs = loader.load()\n",
    "\n",
    "giga = GigaChat(user=\"<user_name>\", password=\"<password>\")\n",
    "chain = load_summarize_chain(giga, chain_type=\"stuff\")\n",
    "\n",
    "chain.run(docs)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "615b36e1",
   "metadata": {},
   "source": [
    "## Подход 1. Stuff\n",
    "\n",
    "When we use `load_summarize_chain` with `chain_type=\"stuff\"`, we will use the [StuffDocumentsChain](/docs/modules/chains/document/stuff).\n",
    "\n",
    "The chain will take a list of documents, inserts them all into a prompt, and passes that prompt to an LLM:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ef45585d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The article discusses the concept of building autonomous agents powered by large language models (LLMs). It explores the components of such agents, including planning, memory, and tool use. The article provides case studies and examples of proof-of-concept demos, highlighting the challenges and limitations of LLM-powered agents. It also includes references to related research papers and provides a citation for the article.\n"
     ]
    }
   ],
   "source": [
    "from langchain.chains.combine_documents.stuff import StuffDocumentsChain\n",
    "from langchain.chains.llm import LLMChain\n",
    "from langchain.chat_models import ChatOpenAI\n",
    "from langchain.prompts import PromptTemplate\n",
    "\n",
    "# Define prompt\n",
    "prompt_template = \"\"\"Write a concise summary of the following:\n",
    "\"{text}\"\n",
    "CONCISE SUMMARY:\"\"\"\n",
    "prompt = PromptTemplate.from_template(prompt_template)\n",
    "\n",
    "# Define LLM chain\n",
    "llm = ChatOpenAI(temperature=0, model_name=\"gpt-3.5-turbo-16k\")\n",
    "llm_chain = LLMChain(llm=llm, prompt=prompt)\n",
    "\n",
    "# Define StuffDocumentsChain\n",
    "stuff_chain = StuffDocumentsChain(llm_chain=llm_chain, document_variable_name=\"text\")\n",
    "\n",
    "docs = loader.load()\n",
    "print(stuff_chain.run(docs))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e4e4a43",
   "metadata": {},
   "source": [
    "Great! We can see that we reproduce the earlier result using the `load_summarize_chain`.\n",
    "\n",
    "### Go deeper\n",
    "\n",
    "* You can easily customize the prompt. \n",
    "* You can easily try different LLMs, (e.g., [Claude](/docs/integrations/chat/anthropic)) via the `llm` parameter."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad6cabee",
   "metadata": {},
   "source": [
    "## Подход 2. Map-Reduce\n",
    "\n",
    "Рассмотрим пример суммаризации на основании подхода map-reduce для статей, загружаемых из Википедии.\n",
    "\n",
    "Статья из Википедии загружается целиком с помощью `WikipediaLoader`, после чего с помощью `CharacterTextSplitter` делится на части размером около 5000 символов."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "a1e6773c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parts count: 12\n"
     ]
    }
   ],
   "source": [
    "from langchain.chains.summarize import load_summarize_chain\n",
    "from langchain.chat_models.gigachat import GigaChat\n",
    "from langchain.document_loaders import WikipediaLoader\n",
    "from langchain.text_splitter import CharacterTextSplitter\n",
    "\n",
    "docs = WikipediaLoader(\n",
    "    query=\"Винни-пух\", lang=\"ru\", load_max_docs=1, doc_content_chars_max=1000000\n",
    ").load()\n",
    "split_docs = CharacterTextSplitter(chunk_size=5000, chunk_overlap=500).split_documents(\n",
    "    docs\n",
    ")\n",
    "print(f\"Parts count: {len(split_docs)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bee3c331",
   "metadata": {},
   "source": [
    "Далее с помощью `GigaChat`` выполняется суммаризация каждой части (фаза map). В конце все суммаризированные части объединяются в одну, после чего выполняется суммарная суммаризация."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "1edb1b0d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "Винни-Пух — любимый герой детской литературы XX века, созданный Аланом Милном. Цикл о Винни-Пухе состоит из двух книг: «Винни-Пух» и «Дом на Пуховой опушке». Пересказ Бориса Заходера сохраняет языковую игру и юмор оригинала, соблюдает английскую ментальность, является популярным детским чтением и среди взрослых, особенно научной интеллигенции. Некоторые переводы были выполнены с английского оригинала, а некоторые — с сокращенной версии пересказа Заходера. Переводы Вебера и Вегушина и Лисицкой были опубликованы в 1996 году в издательстве «Моимпекс» с параллельным английским текстом, чтобы облегчить изучение языков. Однако, по мнению критиков, эти переводы не являются точными или научными, а скорее представляют собой игру с традицией или деконструкцию текста. Фильм \"Винни-Пух\" был создан на студии \"Союзмультфильм\" под руководством Федора Хитрука."
     ]
    }
   ],
   "source": [
    "giga = GigaChat(profanity=False, credentials=...)\n",
    "chain = load_summarize_chain(giga, chain_type=\"map_reduce\")\n",
    "res = chain.run(split_docs)\n",
    "\n",
    "print(\"\\n\\n===\")\n",
    "print(res)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e62c21cf",
   "metadata": {},
   "source": [
    "### Погружаемся глубже\n",
    " \n",
    "**Кастомизация** \n",
    "\n",
    "* Вы можете самостоятельно настроить промпты для каждой фазы map-reduce.\n",
    "\n",
    "**Реальные примеры использования**\n",
    "\n",
    "* См. [this blog post](https://blog.langchain.dev/llms-to-improve-documentation/) кейс по анализу взаимодействия с пользователем (вопросы по документации LangChain)!  \n",
    "* Данном посте [repo](https://github.com/mendableai/QA_clustering) представлена кластеризация как средство суммаризации.\n",
    "* Это открывает третий путь, помимо подходов «stuff» или «map-reduce», который стоит рассмотреть.\n",
    "\n",
    "![Image description](../../static/img/summarization_use_case_3.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f08ff365",
   "metadata": {},
   "source": [
    "## Подход 3. Refine\n",
    " \n",
    "[Refine](/docs/modules/chains/document/refine) подход похож на mad-reduce:\n",
    "\n",
    "> Цепочка refine создает ответ, перебирая входные документы и итеративно обновляя свой ответ. В цикле происходит суммаризация каждого документа с добавлением полученной на предыдущем шаге суммаризации предыдущих документов.\n",
    "\n",
    "Вы можете легко запустить эту цепочку, использовав параметр `chain_type=\"refine\"`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "de1dc10e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'The GPT-Engineer project aims to create a repository of code for specific tasks specified in natural language. It involves breaking down tasks into smaller components and seeking clarification from the user when needed. The project emphasizes the importance of implementing every detail of the architecture as code and provides guidelines for file organization, code structure, and dependencies. However, there are challenges in long-term planning and task decomposition, as well as the reliability of the natural language interface. The system has limited communication bandwidth and struggles to adjust plans when faced with unexpected errors. The reliability of model outputs is questionable, as formatting errors and rebellious behavior can occur. The conversation also includes instructions for writing the code, including laying out the core classes, functions, and methods, and providing the code in a markdown code block format. The user is reminded to ensure that the code is fully functional and follows best practices for file naming, imports, and types. The project is powered by LLM (Large Language Models) and incorporates prompting techniques from various research papers.'"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain = load_summarize_chain(llm, chain_type=\"refine\")\n",
    "chain.run(split_docs)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b46f44d",
   "metadata": {},
   "source": [
    "It's also possible to supply a prompt and return intermediate steps."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "f86c8072",
   "metadata": {},
   "outputs": [],
   "source": [
    "prompt_template = \"\"\"Write a concise summary of the following:\n",
    "{text}\n",
    "CONCISE SUMMARY:\"\"\"\n",
    "prompt = PromptTemplate.from_template(prompt_template)\n",
    "\n",
    "refine_template = (\n",
    "    \"Your job is to produce a final summary\\n\"\n",
    "    \"We have provided an existing summary up to a certain point: {existing_answer}\\n\"\n",
    "    \"We have the opportunity to refine the existing summary\"\n",
    "    \"(only if needed) with some more context below.\\n\"\n",
    "    \"------------\\n\"\n",
    "    \"{text}\\n\"\n",
    "    \"------------\\n\"\n",
    "    \"Given the new context, refine the original summary in Italian\"\n",
    "    \"If the context isn't useful, return the original summary.\"\n",
    ")\n",
    "refine_prompt = PromptTemplate.from_template(refine_template)\n",
    "chain = load_summarize_chain(\n",
    "    llm=llm,\n",
    "    chain_type=\"refine\",\n",
    "    question_prompt=prompt,\n",
    "    refine_prompt=refine_prompt,\n",
    "    return_intermediate_steps=True,\n",
    "    input_key=\"input_documents\",\n",
    "    output_key=\"output_text\",\n",
    ")\n",
    "result = chain({\"input_documents\": split_docs}, return_only_outputs=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "d9600b67-79d4-4f85-aba2-9fe81fa29f49",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "L'articolo discute il concetto di costruire agenti autonomi utilizzando LLM (large language model) come controller principale. Esplora i diversi componenti di un sistema di agenti alimentato da LLM, inclusa la pianificazione, la memoria e l'uso di strumenti. Dimostrazioni di concetto come AutoGPT mostrano la possibilità di creare agenti autonomi con LLM come controller principale. Approcci come Chain of Thought, Tree of Thoughts, LLM+P, ReAct e Reflexion consentono agli agenti autonomi di pianificare, riflettere su se stessi e migliorare iterativamente. Tuttavia, ci sono sfide legate alla lunghezza del contesto, alla pianificazione a lungo termine e alla decomposizione delle attività. Inoltre, l'affidabilità dell'interfaccia di linguaggio naturale tra LLM e componenti esterni come la memoria e gli strumenti è incerta. Nonostante ciò, l'uso di LLM come router per indirizzare le richieste ai moduli esperti più adatti è stato proposto come architettura neuro-simbolica per agenti autonomi nel sistema MRKL. L'articolo fa riferimento a diverse pubblicazioni che approfondiscono l'argomento, tra cui Chain of Thought, Tree of Thoughts, LLM+P, ReAct, Reflexion, e MRKL Systems.\n"
     ]
    }
   ],
   "source": [
    "print(result[\"output_text\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "5f91a8eb-daa5-4191-ace4-01765801db3e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This article discusses the concept of building autonomous agents using LLM (large language model) as the core controller. The article explores the different components of an LLM-powered agent system, including planning, memory, and tool use. It also provides examples of proof-of-concept demos and highlights the potential of LLM as a general problem solver.\n",
      "\n",
      "Questo articolo discute del concetto di costruire agenti autonomi utilizzando LLM (large language model) come controller principale. L'articolo esplora i diversi componenti di un sistema di agenti alimentato da LLM, inclusa la pianificazione, la memoria e l'uso degli strumenti. Vengono anche forniti esempi di dimostrazioni di proof-of-concept e si evidenzia il potenziale di LLM come risolutore generale di problemi. Inoltre, vengono presentati approcci come Chain of Thought, Tree of Thoughts, LLM+P, ReAct e Reflexion che consentono agli agenti autonomi di pianificare, riflettere su se stessi e migliorare iterativamente.\n",
      "\n",
      "Questo articolo discute del concetto di costruire agenti autonomi utilizzando LLM (large language model) come controller principale. L'articolo esplora i diversi componenti di un sistema di agenti alimentato da LLM, inclusa la pianificazione, la memoria e l'uso degli strumenti. Vengono anche forniti esempi di dimostrazioni di proof-of-concept e si evidenzia il potenziale di LLM come risolutore generale di problemi. Inoltre, vengono presentati approcci come Chain of Thought, Tree of Thoughts, LLM+P, ReAct e Reflexion che consentono agli agenti autonomi di pianificare, riflettere su se stessi e migliorare iterativamente. Il nuovo contesto riguarda l'approccio Chain of Hindsight (CoH) che permette al modello di migliorare autonomamente i propri output attraverso un processo di apprendimento supervisionato. Viene anche presentato l'approccio Algorithm Distillation (AD) che applica lo stesso concetto alle traiettorie di apprendimento per compiti di reinforcement learning.\n"
     ]
    }
   ],
   "source": [
    "print(\"\\n\\n\".join(result[\"intermediate_steps\"][:3]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ed720bd-4041-4334-8a98-8baf3b86cc7a",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## Подход 4. Conditional\n",
    "Данная цепочка позволяет выполнять суммаризацию методом stuff, если общий размер документов\n",
    "не превышает параметр max_length (max_length указывается в количество токенов)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "9d74e6e8-28f0-4176-b2e5-dba824b903b0",
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from langchain.chains.summarize import load_summarize_chain\n",
    "from langchain.chat_models.gigachat import GigaChat\n",
    "\n",
    "giga = GigaChat(profanity=False, model=\"GigaChat\", user=\"<юзер>\", password=\"<пароль>\")\n",
    "\n",
    "ch = load_summarize_chain(\n",
    "    llm=giga, chain_type=\"conditional\", verbose=True, max_length=1000\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "495103fe-e555-4abf-aa72-d9cdc2f0eca8",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "В случае ниже статья не превышает 1000 токенов, поэтому мы суммаризуем её методом Stuff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "57c05d67-595c-488e-b4fc-2e015f4bdc29",
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parts count: 1\n",
      "\n",
      "\n",
      "\u001b[1m> Entering new LLMChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mНапиши краткое резюме следующего:\n",
      "\n",
      "\n",
      "\"Улица Винни-Пуха (польск. Ulica Kubusia Puchatka) — улица в Средместье Варшавы, которая проходит от улицы Святокрестской до улицы Варецкой.\n",
      "Улица была заложена в первой половине 1950-х годов на месте руин зданий, разрушенных во время Второй мировой войны, и предназначалась для разгрузки улицы Новый Свят. Проект застройки улицы разработан архитектором Зигмунтом Стемпиньским и студентами Варшавского технологического университета.\n",
      "Улица имеет длину 149 метров и ширину 23 метра, застроена четырёхэтажными жилыми зданиями, первые этажи которых предназначены для магазинов и офисов. Вдоль улицы в 1954 году были высажены два ряда лип, специально завезённых из Щецина. Неподалеку расположена станция 2-й линии варшавского метро Новы Свят — Универсытет.\n",
      "Улица названа в честь персонажа известной сказки Алана Милна — плюшевого медвежонка Винни-Пуха, который изображен на табличке с названием в компании своего друга Пятачка. Помимо Варшавы, улицы Винни-Пуха есть также в Ольштыне и Познани.\n",
      "== Галерея ==\n",
      "== Примечания ==\n",
      "== Ссылки ==\n",
      "Улица Винни-Пуха (польск.)\"\n",
      "\n",
      "\n",
      "КРАТКОЕ РЕЗЮМЕ:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n",
      "Улица Винни-Пуха — это улица в Варшаве, Польша, которая была заложена в 1950-х годах на месте разрушенных зданий. Она имеет длину 149 метров и ширину 23 метра, застроена четырехэтажными жилыми зданиями. Вдоль улицы расположены липы, привезенные из Щецина. Улица названа в честь персонажа известной сказки Алана Милна — Винни-Пуха. Также улицы Винни-Пуха есть в Ольштыне и Познани.\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "from langchain.document_loaders import WikipediaLoader\n",
    "from langchain.schema import Document\n",
    "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
    "\n",
    "docs = WikipediaLoader(\n",
    "    query=\"Улица Винни-Пуха (Варшава)\",\n",
    "    lang=\"ru\",\n",
    "    load_max_docs=1,\n",
    "    doc_content_chars_max=1000000,\n",
    ").load()\n",
    "# Убираем лишние новые линии\n",
    "docs = [\n",
    "    Document(page_content=re.sub(r\"\\n\\s*\\n\", \"\\n\", doc.page_content)) for doc in docs\n",
    "]\n",
    "split_docs = RecursiveCharacterTextSplitter(\n",
    "    chunk_size=5000, chunk_overlap=500\n",
    ").split_documents(docs)\n",
    "print(f\"Parts count: {len(split_docs)}\")\n",
    "print(ch.run(split_docs))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad85e590-9d10-44ac-9340-3cae70c0c39d",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "В случае ниже, у нас документы превышают 1000 токенов, поэтому мы используем Map-Reduce"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "00eea0fa-4ee0-4671-8eb9-05cee74524f5",
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parts count: 2\n",
      "\n",
      "\n",
      "\u001b[1m> Entering new LLMChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mНапиши краткое резюме следующего:\n",
      "\n",
      "\n",
      "\"«Ви́нни-Пух» — первый мультипликационный фильм цикла из трёх советских рисованных мультфильмов по одноимённой сказке А. Милна:\n",
      "Винни-Пух (1969) (10 мин 42 с);\n",
      "Винни-Пух идёт в гости (1971) (9 мин 58 с);\n",
      "Винни-Пух и день забот (1972) (19 мин 25 с).\n",
      "== Сюжет ==\n",
      "Неугомонный медвежонок, идя по лесу и напевая песенки, встречает высокий-превысокий дуб с мёдом в улье на верхушке и с пчёлами. Сначала он пытается самовольно добраться до мёда, но ветка ломается, и он падает в репейник.\n",
      "Тогда медвежонок отправился к своему лучшему другу — поросёнку Пятачку, который жил в домике с надписью «Посторонним В». Сняв колючки с носа, он попросил у него воздушный шарик, и тот дал ему синий шар. Желая замаскироваться под «тучку», Винни-Пух окунается в лужу. Возле дуба Винни-Пух надувает шар побольше, поскольку Пятачок не сумел и чуть не улетел, и воспаряет к улью.\n",
      "Но Винни-Пуху, желавшему «утащить мёд», всячески препятствуют пчёлы и даже начинают жалить его. Тогда медвежонок придумывает хитроумный план: он просит Пятачка открывать зонтик и ходить взад-вперёд, поговаривая: «Кажется, дождь собирается», а сам решил напевать «тучкины песни».\n",
      "В конце-концов, поняв, что «это неправильные пчёлы, и они делают неправильно мёд», Винни-Пух решает спуститься на землю и просит Пятачка принести ружьё и сбить шар. Пятачку с третьей попытки удаётся сбить шар, и Винни-Пух приземляется на землю и отряхивает с себя грязь. Затем все уходят подкрепляться.\n",
      "== История создания ==\n",
      "Как вспоминал режиссёр картины Фёдор Хитрук, при подборе актёров для озвучивания главных героев мультфильмов о Винни-Пухе возникли сложности. Перепробовали множество актёров, но никто не подходил. Попробовали Евгения Леонова, но его голос также оказался слишком низким и не устроил создателя мультфильма. Тогда звукооператор Георгий Мартынюк предложил немного ускорить голос быстрой перемоткой плёнки — результат оказался замечательным. Голос попал точно в персонажа. Тот же приём использовали для других героев мультфильма.\n",
      "Как признавалась Ия Саввина, она, озвучивая Пятачка, слегка пародировала манеру говорить Беллы Ахмадулиной в роли журналистки в фильме «Живёт такой парень».\n",
      "=== Стиль мультфильма ===\n",
      "Художественное решение мультфильма объединяет «детские» рисунки фонов (например, на заднем плане видны огромные улитки, стрекозы, сидящие на гигантских грибах; деревья, на которых одновременно растут яблоки, сливы и какие-то другие фрукты) и передовые для своего времени плавные цветопереходы в рисунках персонажей (исчезли со 2-й серии). Действие разворачивается на плоскости, как обычно происходит в работах Фёдора Хитрука.\n",
      "Вокруг вступительных титров также присутствуют «детские» рисунки бабочек, рыбок, птиц и т. п.\n",
      "== Создатели ==\n",
      "Авторы сценария: Борис Заходер, Фёдор Хитрук\n",
      "Режиссёр: Фёдор Хитрук\n",
      "Композитор: Моисей Вайнберг\n",
      "Художники-постановщики: Владимир Зуйков, Эдуард Назаров\n",
      "Оператор: Нина Климова\n",
      "Звукооператор: Георгий Мартынюк\n",
      "Редактор: Раиса Фричинская\n",
      "Ассистенты: Валентина Гилярова, Татьяна Домбровская\n",
      "Монтажёр: Нина Майорова\n",
      "Мультипликаторы: Наталия Богомолова, Светлана Жутовская, Виолетта Колесникова, Мария Мотрук, Геннадий Сокольский\n",
      "Художники: Ольга Воробьёва, Татьяна Казанцева, Мстислав Купрач (в титрах Ольга Купрач), София Митрофанова\n",
      "Директор картины: Любовь Бутырина\n",
      "== Роли озвучивали ==\n",
      "== Музыка ==\n",
      "3 песни:\n",
      "«Песенка Винни-Пуха», исполняет Евгений Леонов.\n",
      "«Куда идем мы с Пятачком», исполняют Евгений Леонов и Ия Саввина.\n",
      "«Тучка», исполняет Евгений Леонов.\n",
      "== Признание ==\n",
      "В 1976 году за работу над фильмом режиссёр Фёдор Хитрук был удостоен Государственной премии СССР.\n",
      "В 2017 году в честь цикла мультфильмов Банк России выпустил два вида памятных монет — в обычном исполнении номиналом 25 рублей и в особом исполнении из серебра номиналом 3 рубля.\n",
      "Кадры из мультфильма изображены на почтовых марках СССР 1988 года и России 2012 года.\n",
      "== Видеоиздания ==\n",
      "В 1980-е годы мультфильм был выпущен на видеокассетах предприятием «Видеопрограмма Госкино СССР», позже — «Электроника Видео». В 1992 году мультфильм выпущен на видеокассетах кинообъединением «Крупный план»\n",
      "В середине 1990-х годов был выпущен совместно с компанией «Видеомир» в сборнике лучших советских мультфильмов Studio PRO Video и студией «Союз» на VHS, на компакт-дисках Video CD объединением «Крупный план» и компанией «Лизард».\n",
      "В 2000-е годы мультфильм был выпущен на DVD-дисках в 1-м выпуске «Золотой коллекции любимых мультфильмов». Мультфильм был также выпущен на DVD компанией «Крупный план».\n",
      "== Аудиоиздания ==\n",
      "В 1995 году были выпущены аудиосказки по мультфильмам из серии о Винни-Пухе с текстом Александра Пожарова на компактных аудиокассетах фирмой «Твик Лирек».\"\n",
      "\n",
      "\n",
      "КРАТКОЕ РЕЗЮМЕ:\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mНапиши краткое резюме следующего:\n",
      "\n",
      "\n",
      "\"В 2000-е годы мультфильм был выпущен на DVD-дисках в 1-м выпуске «Золотой коллекции любимых мультфильмов». Мультфильм был также выпущен на DVD компанией «Крупный план».\n",
      "== Аудиоиздания ==\n",
      "В 1995 году были выпущены аудиосказки по мультфильмам из серии о Винни-Пухе с текстом Александра Пожарова на компактных аудиокассетах фирмой «Твик Лирек».\n",
      "Песенки из мультфильма были выпущены фирмой «Мелодия» в сборниках «Песенки из мультфильмов» на детских пластинках (Д-00030781 и другие), магнитофонных бобинах и компакт-кассетах «Свема». В 1990-е годы песенки выпущены предприятием «Апрелевка Саунд» на пластинках, аудиокассетах и компакт-дисках, позже — только на кассетах и аудиодисках другими компаниями — в первую очередь, «Твик Лирек».\n",
      "== Примечания ==\n",
      "== Литература ==\n",
      "Освальд Айтен (Oswald Iten). Пух Райтермана и Пух Хитрука: сравнительная характеристика персонажей = Pooh vs. Pukh, a character analysis // Сolorful animation expressions, Швейцария (2011) (англ.) // ИноСМИ.ру. — 2012.\n",
      "Хитрук Ф. С. О зарождении идеи фильма Киноведческие записки № 73, 2005\n",
      "== Ссылки ==\n",
      " «Винни-Пух»\n",
      "«Винни-Пух» — смотрели все, все, все // Наш фильм.ру\n",
      "Кадры из мультфильма\n",
      "Памятник героям мультфильма в Москве\"\n",
      "\n",
      "\n",
      "КРАТКОЕ РЕЗЮМЕ:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n",
      "\n",
      "\n",
      "\u001b[1m> Entering new LLMChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mНапиши краткое резюме следующего:\n",
      "\n",
      "\n",
      "\"\"Винни-Пух\" — советский мультфильм, основанный на одноименной сказке Алана Милна. Фильм состоит из трех частей, каждая из которых длится около десяти минут. Медвежонок Винни-Пух отправляется в лес, где встречает дуб с медом и пчелами. Он пытается достать мед, но пчелы препятствуют ему. В конце концов, Винни-Пух понимает, что неправильные пчелы делают неправильный мед, и решает спуститься на землю. Мультфильм был создан режиссером Фёдором Хитруком и композитором Моисеем Вайнбергом.\n",
      "\n",
      "В 2000-е годы мультфильм \"Винни-Пух\" был выпущен на DVD-дисках в 1-м выпуске \"Золотой коллекции любимых мультфильмов\". Также он был выпущен на DVD компанией \"Крупный план\". В 1995 году были выпущены аудиосказки по мультфильмам из серии о Винни-Пухе на компактных аудиокассетах фирмой \"Твик Лирек\". Песенки из мультфильма были выпущены фирмой \"Мелодия\" в сборниках на детских пластинках, магнитофонных бобинах и компакт-кассетах \"Свема\". В 1990-е годы песенки выпущены предприятием \"Апрелевка Саунд\" на пластинках, аудиокассетах и компакт-дисках. Кадры из мультфильма можно найти на сайте \"Наш фильм.ру\".\"\n",
      "\n",
      "\n",
      "КРАТКОЕ РЕЗЮМЕ:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n",
      "Советский мультфильм \"Винни-Пух\" основан на сказке Алана Милна. Фильм состоит из трех частей и длится около десяти минут. Медвежонок Винни-Пух отправляется в лес, где встречает дуб с медом и пчелами. Он пытается достать мед, но пчелы препятствуют ему. В конце концов, Винни-Пух понимает, что неправильные пчелы делают неправильный мед, и решает спуститься на землю. Мультфильм был создан режиссером Фёдором Хитруком и композитором Моисеем Вайнбергом.\n"
     ]
    }
   ],
   "source": [
    "docs = WikipediaLoader(\n",
    "    query=\"Винни-Пух (мультфильм)\",\n",
    "    lang=\"ru\",\n",
    "    load_max_docs=1,\n",
    "    doc_content_chars_max=1000000,\n",
    ").load()\n",
    "# Убираем лишние новые линии\n",
    "docs = [\n",
    "    Document(page_content=re.sub(r\"\\n\\s*\\n\", \"\\n\", doc.page_content)) for doc in docs\n",
    "]\n",
    "split_docs = RecursiveCharacterTextSplitter(\n",
    "    chunk_size=5000, chunk_overlap=500\n",
    ").split_documents(docs)\n",
    "print(f\"Parts count: {len(split_docs)}\")\n",
    "print(ch.run(split_docs))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
